unit FFT;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

type
  TDirection = (dDirect, dInverse);

  TFFT = class(TComponent)
   private
    { Private declarations }
     PSize : integer;
     PDirection : TDirection;
     procedure SetSize(Value : integer);
     procedure SetDirection(Value : TDirection);
  protected
    { Protected declarations }
  public
    { Public declarations }
     constructor Create(aOwner:Tcomponent); override;
     destructor destroy; override;
     procedure DoFFT(VAR data:array of double);
  published
    { Published declarations }
    property Size : integer read PSize write SetSize;
    property Direction : TDirection read PDirection write SetDirection default dDirect;
  end;

procedure Register;

implementation

procedure TFFT.DoFFT(VAR data:array of double);
var
   ii,jj,n,mmax,m,j,istep,i,isign,nn: integer;
   wtemp,wr,wpr,wpi,wi,theta: double;
   tempr,tempi: double;
begin
   nn := PSize shr 1;

   if PDirection in [dDirect] then
      isign := 1
   else
      isign := -1;
   n := nn shl 1;
   j := 1;
   for ii := 1 to nn do
   begin
      i := 2*ii-1;
      if (j > i) then
      begin
         tempr := data[j];
         tempi := data[j+1];
         data[j] := data[i];
         data[j+1] := data[i+1];
         data[i] := tempr;
         data[i+1] := tempi
      end;
      m := n shr 1;
      while ((m >= 2) AND (j > m))  DO
      begin
         j := j-m;
         m := m shr 1;
      end;
      j := j+m
   end;
   mmax := 2;
   while (n > mmax) do
   begin
      istep := 2*mmax;
      theta := (2 * PI)/(isign*mmax);
      wpr := -2.0*sqr(sin(0.5*theta));
      wpi := sin(theta);
      wr := 1.0;
      wi := 0.0;
      for ii := 1 to (mmax shr 1) do
      begin
         m := 2*ii-1;
         for jj := 0 to ((n-m) DIV istep) do
         begin
            i := m + jj*istep;
            j := i+mmax;
            tempr := (wr)*data[j]-(wi)*data[j+1];
            tempi := (wr)*data[j+1]+(wi)*data[j];
            data[j] := data[i]-tempr;
            data[j+1] := data[i+1]-tempi;
            data[i] := data[i]+tempr;
            data[i+1] := data[i+1]+tempi
         end;
         wtemp := wr;
         wr := wr*wpr-wi*wpi+wr;
         wi := wi*wpr+wtemp*wpi+wi
      end;
      mmax := istep
   end;
end;

constructor TFFT.Create(aOwner:Tcomponent);
Begin
  inherited Create(aOwner);
  SetSize(512);
End;

Destructor TFFT.Destroy;
Begin
  inherited Destroy;
End;

procedure TFFT.SetSize(Value : integer);
begin
   PSize := Value;
end;

procedure TFFT.SetDirection(Value : TDirection);
begin
   PDirection := Value;
end;

procedure Register;
begin
  RegisterComponents('Hps', [TFFT]);
end;

end.


